
import SparkMD5 from 'spark-md5'
import TYPEMAP from './filetype.json'
const getHeaderValue = (value, n) => {
    const arr = (new Uint8Array(value))
    let header = ""
    for (let i = 0; i < arr.length; i++) {
        const v = arr[i].toString(16)
        header += v.length === 1 && v === '0' ? '0' + v : v
    }
    return header
}
/**
 * file header get type
 * @param {*} value16 
 * @param {*} change 
 */
const handleFileType = (value16) => {
    let header3 = value16.substring(0, 3 * 2)
        , header4 = value16.substring(0, 4 * 2)
        , header8 = value16.substring(0, 16 * 2)
    let type = TYPEMAP[header4] || TYPEMAP[header3] || ''
    if (type === '') {
        for (let key of Object.keys(TYPEMAP)) {
            let arr = key.split(/\{\d+,\d+\}/, 2)
            if (!arr[1]) {
                continue
            }
            if (header8.substring(0, arr[0].length) === arr[0]) {
                const siteArr = key.match(/\{(\d+,\d+)\}/)[1].split(',').map(e => e | 0)
                const startSite = arr[1].length + siteArr[0] + 2
                if (header8.substring(startSite, startSite + siteArr[1]) === arr[1]) {
                    type = TYPEMAP[key]
                    break
                }
            } else {
                continue
            }
        }
    }
   return type
}
function getFileType(value16) {
    return handleFileType(getHeaderValue(value16))
}
self.addEventListener('message', function (e) {
    const data = e.data
    const { chunkSize, files } = data
    for (const file of files) {
        createChunkFile(file, chunkSize, files.length)
    }
    // self.postMessage(data)
})
async function getFileMd5 (chunk) {
    let spark = new SparkMD5.ArrayBuffer()
    return new Promise((resolve, reject)=>{
        const fileReader = new FileReader()
        fileReader.readAsArrayBuffer(chunk)
        fileReader.onload = (e)=> {
            spark.append(e.target.result)
            resolve(spark.end())
        }
        fileReader.onerror = (e) => {
            reject(e)
        } 
    })
}
async function createChunkFile(file, chunkSize, totalLength) {
    console.log('worker create file chunk')
    let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
    let chunkTotal = Math.ceil(file.size / chunkSize) - 1
    let currentChunk = 0
    let fileHash = null
    
    let chunks = []
    let fileType = null
    for(currentChunk = 0; currentChunk <= chunkTotal; currentChunk++) {
        let start = currentChunk * chunkSize
        let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize
        let chunk = blobSlice.call(file, start, end)
        // 只获取前1m的数据来生成文件hash
        if (currentChunk === 0 && !fileHash) {
            fileHash = await getFileMd5(chunk)
            fileType = getFileType(chunk)
        }
        chunks.push({
            id: currentChunk,
            parentHash: fileHash,
            chunk: chunk
        })
    }
    // console.log()
    postMessage({
        fileHash,
        chunks,
        name: file.name,
        chunkTotal,
        fileType,
        filesLength: totalLength
    })
}
